using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Authentication.OpenIdConnect;
using Microsoft.AspNetCore.Authorization;
using AspNetCore.Proxy;
using Web.Bff;
using Web.Bff.Middlewares;

var builder = WebApplication.CreateBuilder(args);
var configuration = builder.Configuration;
var env = builder.Environment;
var services = builder.Services;

services
    .AddSecurity(configuration)
    .ApplyYarp(configuration)
    .AddServiceDiscovery(configuration);

services.AddCors(options =>
{
    options.AddPolicy("Bff", policy =>
    {
        policy.WithOrigins("http://localhost:5173", "https://localhost:5173")
            .AllowAnyHeader()
            .AllowAnyMethod()
            .AllowCredentials();
    });
});

if (env.IsDevelopment())
{
    services.AddProxies();
}

var app = builder.Build();
app.UseSecurityHeaders(SecurityHeadersDefinitions
    .GetHeaderPolicyCollection(env.IsDevelopment(), configuration["idp"]));
app.UseMiddleware<XsrfTokenMiddleware>();

if (app.Environment.IsDevelopment())
{
    app.UseDeveloperExceptionPage();
}
else
{
    app.UseExceptionHandler("/Error");
    app.UseHsts();
}

app.UseStaticFiles();
app.UseRouting();
app.UseCors("Bff");
app.UseAuthentication();
app.UseAuthorization();
app.MapReverseProxy();

app.MapReverseProxy();

app.MapGet("/login", (string? returnUrl) =>
{
    var props = new AuthenticationProperties { RedirectUri = returnUrl ?? "/" };
    return Results.Challenge(props, [OpenIdConnectDefaults.AuthenticationScheme]);
});

app.MapGet("/logout", (string? returnUrl) =>
{
    var props = new AuthenticationProperties { RedirectUri = returnUrl ?? "/" };
    return Results.SignOut(
        props,
        [
            CookieAuthenticationDefaults.AuthenticationScheme,
            OpenIdConnectDefaults.AuthenticationScheme
        ]);
});

app.MapGet("/api/me", [Authorize] (HttpContext ctx) =>
{
    var user = new {
        ctx.User.Identity?.Name,
        Claims = ctx.User.Claims.Select(c => new { c.Type, c.Value })
    };
    return Results.Json(user);
});

await app.RunAsync();
